home *** CD-ROM | disk | FTP | other *** search
/ PC World 2007 December / PCWorld_2007-12_cd.bin / v cisle / htttrack / httrack-3.41-3.exe / {app} / src / proxy / proxytrack.h < prev    next >
C/C++ Source or Header  |  2006-10-15  |  11KB  |  395 lines

  1. /* ------------------------------------------------------------ */
  2. /*
  3. HTTrack Website Copier, Offline Browser for Windows and Unix
  4. Copyright (C) Xavier Roche and other contributors
  5.  
  6. This program is free software; you can redistribute it and/or
  7. modify it under the terms of the GNU General Public License
  8. as published by the Free Software Foundation; either version 2
  9. of the License, or any later version.
  10.  
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with this program; if not, write to the Free Software
  18. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  19.  
  20. Please visit our Website: http://www.httrack.com
  21. */
  22.  
  23. /* ------------------------------------------------------------ */
  24. /* File: ProxyTrack, httrack cache-based proxy                  */
  25. /* Author: Xavier Roche                                         */
  26. /* ------------------------------------------------------------ */
  27.  
  28. #ifndef WEBHTTRACK_PROXYTRACK
  29. #define WEBHTTRACK_PROXYTRACK
  30.  
  31. /* Version */
  32. #define PROXYTRACK_VERSION "0.5"
  33.  
  34. /* Store manager */
  35. #include "../minizip/mztools.h"
  36. #include "store.h"
  37.  
  38. #include <sys/stat.h>
  39. #ifndef HTS_DO_NOT_USE_FTIME
  40. #ifdef _WIN32
  41. #include <sys/utime.h>
  42. #else
  43. #include <utime.h>
  44. #endif
  45. #include <sys/timeb.h>
  46. #else
  47. #include <utime.h>
  48. #endif
  49. #ifndef _WIN32
  50. #include <pthread.h>
  51. #endif
  52.  
  53. /* generic */
  54.  
  55. int proxytrack_main(char* proxyAddr, int proxyPort, 
  56.                                         char* icpAddr, int icpPort, 
  57.                                         PT_Indexes index);
  58.  
  59. /* Spaces: CR,LF,TAB,FF */
  60. #define  is_space(c)      ( ((c)==' ') || ((c)=='\"') || ((c)==10) || ((c)==13) || ((c)==9) || ((c)==12) || ((c)==11) || ((c)=='\'') )
  61. #define  is_realspace(c)  ( ((c)==' ')                || ((c)==10) || ((c)==13) || ((c)==9) || ((c)==12) || ((c)==11)                )
  62. #define  is_taborspace(c) ( ((c)==' ')                                          || ((c)==9)                             )
  63. #define  is_quote(c)      (               ((c)=='\"')                                                    || ((c)=='\'') )
  64. #define  is_retorsep(c)   (                              ((c)==10) || ((c)==13) || ((c)==9)                                          )
  65.  
  66. /* Static definitions */
  67.  
  68. #define _ ,
  69. #define CRITICAL_(msg, file, line) do { \
  70.     fprintf(stderr, "* critical: "); \
  71.     fprintf(stderr, msg); \
  72.     fprintf(stderr, " at %s:%d\n", file, line); \
  73.     fflush(stderr); \
  74. } while(0)
  75. #define CRITICAL(msg) do { \
  76.     fprintf(stderr, "* critical: "); \
  77.     fprintf(stderr, msg); \
  78.     fprintf(stderr, " at %s:%d\n", __FILE__, __LINE__); \
  79.     fflush(stderr); \
  80. } while(0)
  81.  
  82. #define WARNING(msg) do { \
  83.     fprintf(stderr, "* warning: "); \
  84.     fprintf(stderr, msg); \
  85.     fprintf(stderr, "\n"); \
  86.     fflush(stderr); \
  87. } while(0)
  88.  
  89. #define LOG(msg) do { \
  90.     fprintf(stderr, "* log: "); \
  91.     fprintf(stderr, msg); \
  92.     fprintf(stderr, "\n"); \
  93.     fflush(stderr); \
  94. } while(0)
  95.  
  96. #if defined(_DEBUG) || defined(DEBUG)
  97. #define DEBUG(msg) do { \
  98.     fprintf(stderr, "* debug: "); \
  99.     fprintf(stderr, msg); \
  100.     fprintf(stderr, "\n"); \
  101.     fflush(stderr); \
  102. } while(0)
  103. #else
  104. #define DEBUG_(msg, file, line) do { } while(0)
  105. #define DEBUG(msg) do { } while(0)
  106. #endif
  107.  
  108. /* Header for generated pages */
  109. #define PROXYTRACK_COMMENT_HEADER \
  110.     "<!-- Generated by ProxyTrack " PROXYTRACK_VERSION " build " __DATE__ " -->\r\n" \
  111.     "<!-- This is an add-on for HTTrack " HTTRACK_VERSIONID " -->\r\n"
  112.  
  113. /* See IE "feature" (MSKB Q294807) */
  114. #define DISABLE_IE_FRIENDLY_HTTP_ERROR_MESSAGES                                            \
  115.     "<!-- Start Disable IE Friendly HTTP Error Messages -->\r\n"            \
  116.     "<!-- _-._.--._._-._.--._._-._.--._._-._.--._._-._.--._. -->\r\n" \
  117.     "<!-- _-._.--._._-._.--._._-._.--._._-._.--._._-._.--._. -->\r\n" \
  118.     "<!-- _-._.--._._-._.--._._-._.--._._-._.--._._-._.--._. -->\r\n" \
  119.     "<!-- _-._.--._._-._.--._._-._.--._._-._.--._._-._.--._. -->\r\n" \
  120.     "<!-- _-._.--._._-._.--._._-._.--._._-._.--._._-._.--._. -->\r\n" \
  121.     "<!-- _-._.--._._-._.--._._-._.--._._-._.--._._-._.--._. -->\r\n" \
  122.     "<!-- _-._.--._._-._.--._._-._.--._._-._.--._._-._.--._. -->\r\n" \
  123.     "<!-- _-._.--._._-._.--._._-._.--._._-._.--._._-._.--._. -->\r\n" \
  124.     "<!-- _-._.--._._-._.--._._-._.--._._-._.--._._-._.--._. -->\r\n" \
  125.     "<!-- _-._.--._._-._.--._._-._.--._._-._.--._._-._.--._. -->\r\n" \
  126.     "<!-- End Disable IE Friendly HTTP Error Messages -->\r\n"
  127.  
  128. static char* gethomedir(void) {
  129.   char* home = getenv( "HOME" );
  130.   if (home)
  131.     return home;
  132.   else
  133.     return ".";
  134. }
  135.  
  136. static int linput(FILE* fp,char* s,int max) {
  137.   int c;
  138.   int j=0;
  139.   do {
  140.     c=fgetc(fp);
  141.     if (c!=EOF) {
  142.       switch(c) {
  143.         case 13: break;  // sauter CR
  144.         case 10: c=-1; break;
  145.         case 0: case 9: case 12: break;  // sauter ces caractΦres
  146.         default: s[j++]=(char) c; break;
  147.       }
  148.     }
  149.   }  while((c!=-1) && (c!=EOF) && (j<(max-1)));
  150.   s[j]='\0';
  151.   return j;
  152. }
  153.  
  154. static int link_has_authority(const char* lien) {
  155.   const char* a=lien;
  156.   if (isalpha((const unsigned char)*a)) {
  157.     // Skip scheme?
  158.     while (isalpha((const unsigned char)*a))
  159.       a++;
  160.     if (*a == ':')
  161.       a++;
  162.     else
  163.       return 0;
  164.   }
  165.   if (strncmp(a,"//",2) == 0)
  166.     return 1;
  167.   return 0;
  168. }
  169.  
  170. static const char* jump_protocol(const char* source) {
  171.   int p;
  172.   // scheme
  173.   // "Comparisons of scheme names MUST be case-insensitive" (RFC2616)
  174.   if ((p = strfield(source,"http:")))
  175.     source+=p;
  176.   else if ((p = strfield(source,"ftp:")))
  177.     source+=p;
  178.   else if ((p = strfield(source,"https:")))
  179.     source+=p;
  180.   else if ((p = strfield(source,"file:")))
  181.     source+=p;
  182.   else if ((p = strfield(source,"mms:")))
  183.     source+=p;
  184.   // net_path
  185.   if (strncmp(source,"//",2)==0)
  186.     source+=2;
  187.   return source;
  188. }
  189.  
  190. static const char* strrchr_limit(const char* s, char c, const char* limit) {
  191.   if (limit == NULL) {
  192.     char* p = strrchr(s, c);
  193.     return p?(p+1):NULL;
  194.   } else {
  195.     char *a=NULL, *p;
  196.     for(;;) {
  197.       p=strchr((a)?a:s, c);
  198.       if ((p >= limit) || (p == NULL))
  199.         return a;
  200.       a=p+1;
  201.     }
  202.   }
  203. }
  204.  
  205. static const char* jump_protocol_and_auth(const char* source) {
  206.   const char *a,*trytofind;
  207.   if (strcmp(source, "file://") == 0)
  208.       return source;
  209.   a = jump_protocol(source);
  210.   trytofind = strrchr_limit(a, '@', strchr(a,'/'));
  211.   return (trytofind != NULL)?trytofind:a;
  212. }
  213.  
  214. #ifndef min
  215. #define min(a,b) ((a)>(b)?(b):(a))
  216. #endif
  217. #ifndef max
  218. #define max(a,b) ((a)>(b)?(a):(b))
  219. #endif
  220. static int linput_trim(FILE* fp,char* s,int max) {
  221.   int rlen=0;
  222.   char* ls=(char*) malloc(max+2);
  223.   s[0]='\0';
  224.   if (ls) {
  225.     char* a;
  226.     // lire ligne
  227.     rlen=linput(fp,ls,max);
  228.     if (rlen) {
  229.       // sauter espaces et tabs en fin
  230.       while( (rlen>0) && is_realspace(ls[max(rlen-1,0)]) )
  231.         ls[--rlen]='\0';
  232.       // sauter espaces en dΘbut
  233.       a=ls;
  234.       while((rlen>0) && ((*a==' ') || (*a=='\t'))) {
  235.         a++;
  236.         rlen--;
  237.       }
  238.       if (rlen>0) {
  239.         memcpy(s,a,rlen);      // can copy \0 chars
  240.         s[rlen]='\0';
  241.       }
  242.     }
  243.     //
  244.     free(ls);
  245.   }
  246.   return rlen;
  247. }
  248.  
  249. #ifndef S_ISREG
  250. #define S_ISREG(m) ((m) & _S_IFREG)
  251. #endif
  252. static int fexist(char* s) {
  253.   struct stat st;
  254.   memset(&st, 0, sizeof(st));
  255.   if (stat(s, &st) == 0) {
  256.     if (S_ISREG(st.st_mode)) {
  257.       return 1;
  258.     }
  259.   }
  260.   return 0;
  261.  
  262. /* convertir une chaine en temps */
  263. static void set_lowcase(char* s) {
  264.   int i;
  265.   for(i=0;i<(int) strlen(s);i++)
  266.     if ((s[i]>='A') && (s[i]<='Z'))
  267.       s[i]+=('a'-'A');
  268. }
  269. static struct tm* convert_time_rfc822(struct tm *result,const char* s) {
  270.   char months[]="jan feb mar apr may jun jul aug sep oct nov dec";
  271.   char str[256];
  272.     char* a;
  273.   /* */
  274.   int result_mm=-1;
  275.   int result_dd=-1;
  276.   int result_n1=-1;
  277.   int result_n2=-1;
  278.   int result_n3=-1;
  279.   int result_n4=-1;
  280.   /* */
  281.  
  282.   if ((int) strlen(s) > 200)
  283.     return NULL;
  284.   strcpy(str,s);
  285.   set_lowcase(str);
  286.   /* Θliminer :,- */
  287.   while( (a=strchr(str,'-')) ) *a=' ';
  288.   while( (a=strchr(str,':')) ) *a=' ';
  289.   while( (a=strchr(str,',')) ) *a=' ';
  290.   /* tokeniser */
  291.   a=str;
  292.   while(*a) {
  293.     char *first, *last;
  294.     char tok[256];
  295.     /* dΘcouper mot */
  296.     while(*a==' ') a++;   /* sauter espaces */
  297.     first=a;
  298.     while((*a) && (*a!=' ')) a++;
  299.     last=a;
  300.     tok[0]='\0';
  301.     if (first!=last) {
  302.       char* pos;
  303.       strncat(tok,first,(int) (last - first));
  304.       /* analyser */
  305.       if ( (pos=strstr(months,tok)) ) {               /* month always in letters */
  306.         result_mm=((int) (pos - months))/4;
  307.       } else {
  308.         int number;
  309.         if (sscanf(tok,"%d",&number) == 1) {      /* number token */
  310.           if (result_dd<0)                        /* day always first number */
  311.             result_dd=number;
  312.           else if (result_n1<0)
  313.             result_n1=number;
  314.           else if (result_n2<0)
  315.             result_n2=number;
  316.           else if (result_n3<0)
  317.             result_n3=number;
  318.           else if (result_n4<0)
  319.             result_n4=number;
  320.         }   /* sinon, bruit de fond(+1GMT for exampel) */
  321.       }
  322.     }
  323.   }
  324.   if ((result_n1>=0) && (result_mm>=0) && (result_dd>=0) && (result_n2>=0) && (result_n3>=0) && (result_n4>=0)) {
  325.     if (result_n4>=1000) {               /* Sun Nov  6 08:49:37 1994 */
  326.       result->tm_year=result_n4-1900;
  327.       result->tm_hour=result_n1;
  328.       result->tm_min=result_n2;
  329.       result->tm_sec=max(result_n3,0);
  330.     } else {                            /* Sun, 06 Nov 1994 08:49:37 GMT or Sunday, 06-Nov-94 08:49:37 GMT */
  331.       result->tm_hour=result_n2;
  332.       result->tm_min=result_n3;
  333.       result->tm_sec=max(result_n4,0);
  334.       if (result_n1<=50)                /* 00 means 2000 */
  335.         result->tm_year=result_n1+100;
  336.       else if (result_n1<1000)          /* 99 means 1999 */
  337.         result->tm_year=result_n1;
  338.       else                              /* 2000 */
  339.         result->tm_year=result_n1-1900;
  340.     }
  341.     result->tm_isdst=0;        /* assume GMT */
  342.     result->tm_yday=-1;        /* don't know */
  343.     result->tm_wday=-1;        /* don't know */
  344.     result->tm_mon=result_mm;
  345.     result->tm_mday=result_dd;
  346.     return result;
  347.   }
  348.   return NULL;
  349. }
  350. static struct tm PT_GetTime(time_t t) {
  351.     struct tm tmbuf;
  352. #ifdef _WIN32
  353.     struct tm * tm = gmtime(&t);
  354. #else
  355.     struct tm * tm = gmtime_r(&t, &tmbuf);
  356. #endif
  357.     if (tm != NULL)
  358.         return *tm;
  359.     else {
  360.         memset(&tmbuf, 0, sizeof(tmbuf));
  361.         return tmbuf;
  362.     }
  363. }
  364. static int set_filetime(const char* file, struct tm* tm_time) {
  365.   struct utimbuf tim;
  366. #ifndef HTS_DO_NOT_USE_FTIME
  367.   struct timeb B;
  368.   memset(&B, 0, sizeof(B));
  369.   B.timezone=0;
  370.   ftime( &B );
  371.   tim.actime = tim.modtime = mktime(tm_time) - B.timezone*60; 
  372. #else
  373.   // bogus time (GMT/local)..
  374.   tim.actime=tim.modtime=mktime(tm_time); 
  375. #endif
  376.   return utime(file, &tim);
  377. }
  378. static int set_filetime_time_t(const char* file, time_t t) {
  379.     if (t != (time_t) 0 && t != (time_t) -1) {
  380.         struct tm tm = PT_GetTime(t);
  381.         return set_filetime(file, &tm);
  382.     }
  383.     return -1;
  384. }
  385. static int set_filetime_rfc822(const char* file, const char* date) {
  386.     struct tm buffer;
  387.   struct tm* tm_s = convert_time_rfc822(&buffer,date);
  388.   if (tm_s) {
  389.     return set_filetime(file,tm_s);
  390.   } else return -1;
  391. }
  392.  
  393. #endif
  394.